package cn.bigcontainer.alt.meta.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import cn.bigcontainer.alt.common.util.WoKit;
import cn.bigcontainer.alt.meta.dao.MDao;
import cn.bigcontainer.alt.meta.dto.MAppDto;
import cn.bigcontainer.alt.meta.dto.MObjectDto;
import cn.bigcontainer.alt.meta.exception.MException;
import cn.bigcontainer.alt.meta.mapper.MAppMapper;
import cn.bigcontainer.alt.meta.mapper.MObjectMapper;
import cn.bigcontainer.alt.meta.po.MApp;
import cn.bigcontainer.alt.meta.po.MObject;
import cn.bigcontainer.alt.meta.po.MRelation;
import cn.bigcontainer.alt.meta.po.MViewProperty;
import cn.bigcontainer.alt.meta.service.ObjectInputorService;
import lombok.extern.slf4j.Slf4j;

/**
 * 
 * @author jiaod
 *
 */
@Service
@Transactional(rollbackFor = { Exception.class })
@Primary
@Slf4j
public class ObjectInputorServiceImpl implements ObjectInputorService {

	@Resource
	private MAppMapper appMapper;
	
	@Resource
	private MObjectMapper objectMapper;
	
	@Resource
	private MDao dao;
	
	private static final Integer LIST_MAX = 20;
	
	@Override
	public List<Map<String, Object>> list(String id, String propertyId, String searchContent) {
		MApp app = appMapper.selectById(id);
		MAppDto appDto = new MAppDto(app);
		MViewProperty viewProperty = appDto.getViewProperty(propertyId);
		MRelation relation = viewProperty.getRelation();
		if (relation == null) {
			throw new MException(MException.OI_RELATION);
		}
		String sqlString = "select %s as value, %s as name, '%s' as type from %s where %s like '%%%s%%'";
		String sql = "";
		for (String relatedObjectId : viewProperty.getRelation().getRelatedObjectId().split(",")) {
			MObject relatedObject = objectMapper.selectById(relatedObjectId);
			String nameColumn = MObjectDto.getNameProperty(relatedObject).getName();
			String pk = MObjectDto.getKeyProperties(relatedObject).get(0).getName();
			if (!"".equals(sql)) {
				sql += " union all ";
			}
			sql += String.format(sqlString, pk, nameColumn, relatedObjectId, relatedObjectId, nameColumn, searchContent);
		}
		return dao.queryList(sql);
	}

	@Override
	public List<Map<String, Object>> getValue(String id, String propertyId, String keyValue, String value) {
		MApp app = appMapper.selectById(id);
		MAppDto appDto = new MAppDto(app);
		MViewProperty viewProperty = appDto.getViewProperty(propertyId);
		MRelation relation = viewProperty.getRelation();
		if (relation == null) {
			throw new MException(MException.OI_RELATION2);
		}
		List<Map<String, Object>> resultList = new ArrayList<Map<String,Object>>();
		if (WoKit.isEmpty(keyValue) && WoKit.isEmpty(value)) {
			return resultList;
		}
		switch (relation.getType()) {
		case MRelation.TYPE_M2CM:
			List<Map<String,Object>> list = new ArrayList<Map<String,Object>>();
			if (!WoKit.isEmpty(value)) {
				String[] values = value.split(",");
				for (String v : values) {
					Map<String,Object> row = new HashMap<String, Object>();
					String[] strings = v.split(":");
					row.put("table", strings[0]);
					row.put("tablePkValue", strings[1]);
					list.add(row);
				}
			} else if (!WoKit.isEmpty(keyValue)) {
				String sqlString = "select %s as 'table', %s as tablePkValue from %s where %s = '%s'";
				MObjectDto relationObject = relation.getRelationObject();
				String sql = String.format(sqlString, relationObject.getProperty(relation.getRelationRelatedObjectId()).getName(), 
						relationObject.getProperty(relation.getRelationInverseIds()).getName(), 
						relationObject.getId(), 
						relationObject.getProperty(relation.getRelationIds()).getName(), 
						keyValue);
				list = dao.queryList(sql);
			}
			String[] relatedObjectIds = relation.getRelatedObjectId().split(",");
			String[] relatedPropertyIds = relation.getRelatedIds().split(",,");
			for (int i = 0; i < relatedObjectIds.length; i++) {
				String relatedObjectId = relatedObjectIds[i];
				MObject relatedObject = objectMapper.selectById(relatedObjectId);
				// 名称列名
				String nameColumn = MObjectDto.getNameProperty(relatedObject).getName();
				// 被关联列名
				String relatedColumn = MObjectDto.getProperty(relatedObject, relatedPropertyIds[i]).getName();
				for (Map<String,Object> map : list) {
					if (map.get("table").equals(relatedObjectId)) {
						String sql2 = String.format("select %s as value, %s as name, '%s' as type from %s where %s = '%s'", relatedColumn, nameColumn, relatedObjectId, relatedObjectId, relatedColumn, map.get("tablePkValue").toString());
						List<Map<String,Object>> list2 = dao.queryList(sql2);
						resultList.addAll(list2);
					}
				}
			}
			break;
		default:
			break;
		}
		return resultList;
	}
	
}
